﻿using System;
using System.Security;
using System.Globalization;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Taxonomy;


namespace Core.Foundation.Standards
{

    /// <summary>
    /// Extension classes so we can get and use the Description Attribute
    /// </summary>        
    public static class EnumExtensions
    {
        private const char ENUM_SEPERATOR_CHARACTER = ',';
        public static string GetDescription(Enum value)
        {         
            // Extension method to get the attributes, in-turn getting the Description attribute.
            var description = value.ToString();
            var fieldInfo = value.GetType().GetField(description);
            var attribute = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
         
            return attribute[0].Description;
        }

        public static string Description(this Enum value)
        {            
            // Get the description off of the current Enum Value
            return GetDescription(value);
        }

        public static string ToSafeString(this object obj)
        {
            return (obj ?? string.Empty).ToString();
        }


        
    }
    
    /// <summary>
    ///  Helper class for creating site columns, content types etc.
    /// </summary>
    public class CoreHelper
    {
        #region WebSafeUpdates
        private static Dictionary<Guid, bool> WebState = new Dictionary<Guid, bool>();
        private static Dictionary<Guid, int> WebAppUpdates = new Dictionary<Guid, int>();

        public static void ResetWebSafeDictionaries()
        {
            WebState = new Dictionary<Guid, bool>();
            WebAppUpdates = new Dictionary<Guid, int>();
        }


        public static void AllowUnSafeUpdates(ref SPWeb oWeb, Guid webGuid)
        {
            try
            {
                if (WebAppUpdates[oWeb.ID] == 1)
                {
                    if (WebState.ContainsKey(webGuid))
                    {
                        // last web app - reset the web to original state
                        bool result = WebState[webGuid];

                        if (oWeb.AllowUnsafeUpdates != result)
                        {
                            oWeb.AllowUnsafeUpdates = result;
                        }

                        WebState.Remove(oWeb.ID);
                        WebAppUpdates.Remove(oWeb.ID);
                    }
                }
                else
                {
                    WebAppUpdates[oWeb.ID] -= 1;
                }
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.coreLog);
                throw new Exception("There was an error with safe AllowUnsafeUpdates");
            }
        }

        public static Guid AllowUnSafeUpdates(ref SPWeb oWeb)
        {
            try
            {
                if (WebAppUpdates.ContainsKey(oWeb.ID))
                {
                    WebAppUpdates[oWeb.ID] += 1;
                }
                else
                {
                    WebAppUpdates.Add(oWeb.ID, 1);
                    WebState.Add(oWeb.ID, oWeb.AllowUnsafeUpdates);
                }

                if (oWeb.AllowUnsafeUpdates == false)
                {
                    oWeb.AllowUnsafeUpdates = true;
                }

                return oWeb.ID;
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.coreLog);
                throw new Exception("There was an error with safe AllowUnsafeUpdates");
            }
        }


        #endregion

        #region Core
        public static string GetCoreSiteURL(SPWeb web)
        {
            return web.Site.Protocol + "//" + web.Site.HostName + FoundationConstants.CoreSite;
        }

        public static SPWeb GetCoreWeb()
        {
            try
            {
                SPWeb CoreWeb = null;
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    string CoreURL = string.Empty;
                    foreach (SPService svc in SPFarm.Local.Services)
                    {
                        if (!(svc is SPWebService))
                            continue;

                        foreach (SPWebApplication webApp in ((SPWebService)svc).WebApplications)
                        {
                            foreach (SPPrefix prefix in webApp.Prefixes)
                            {
                                if (prefix.Name.ToUpper() == FoundationConstants.BaseName.ToUpper())
                                {
                                    CoreURL = CoreHelper.GetCoreSiteURL(webApp.Sites[0].RootWeb);
                                    break;
                                }
                            }
                        }
                    }
                    if (CoreURL == string.Empty)
                        throw new Exception("Core Web Not Found!");

                    CoreWeb = new SPSite(CoreURL).OpenWeb();
                });
                return CoreWeb;
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.coreLog);
                return null;
            }
        }

        #endregion

        #region Create Site Columns,Content types, add Site columns to content types & Lists.


        /// <summary>
        /// Adding Column To ContentType
        /// </summary>
        /// <param name="fieldId"></param>
        /// <param name="web"></param>
        /// <param name="contentType"></param>
        public static void AddColumnToContentType(Guid fieldId, SPWeb web, SPContentType contentType)
        {
            try
            {
                //check for any Field links for thos field
                if (HasFieldLink(contentType, fieldId))
                {
                    // if so, delete it before addinng it to content type
                    contentType.FieldLinks.Delete(fieldId);
                    contentType.Update();
                }

                // cretae Field based on id
                SPField Field = web.AvailableFields[fieldId];
                SPFieldLink FieldLink = new SPFieldLink(Field);
                // check for FieldLink existance, if it is not avaialble, add to Content Type
                if (contentType.FieldLinks[FieldLink.Id] == null)
                {
                    // add field to content type
                    contentType.FieldLinks.Add(FieldLink);
                    contentType.Update(true);
                    web.Update();
                }
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }

        }
        /// <summary>
        /// Creating Site Column
        /// </summary>
        /// <param name="web"></param>
        /// <param name="fieldId"></param>
        /// <param name="FieldXml"></param>
        public static void CreateSiteColumn(SPWeb web, Guid fieldId, string FieldXml)
        {


            // check for Field existance, if it is not available,create one.
            if (web.AvailableFields.Contains(fieldId) == false)
            {
                try
                {
                    web.Fields.AddFieldAsXml(FieldXml);
                }
                catch (Exception ex)
                {
                    Logging.LogError(ex, FoundationConstants.standardsLog);
                }
            }
        }

        /// <summary>
        /// An overloaded version that will perform all steps for you
        /// Allows the consumer to call 1 method instead of several to create a column
        /// </summary>
        /// <param name="web"></param>
        /// <param name="FieldId"></param>
        /// <param name="FieldName"></param>
        /// <param name="FieldDisplayName"></param>
        /// <param name="DisplaceOnUpgrade"></param>
        /// <param name="IsHidden"></param>
        /// <param name="IsRequired"></param>
        /// <param name="FieldType"></param>
        /// <param name="FieldFormat"></param>
        /// <param name="SiteColumnGroup"></param>
        /// <param name="FieldChoices"></param>
        public static void CreateSiteColumn(SPWeb web, Guid FieldId, string FieldName, string FieldDisplayName,
            bool DisplaceOnUpgrade, bool IsHidden, bool IsRequired,
            FoundationEnums.FieldTypes FieldType, FoundationEnums.Format FieldFormat, string SiteColumnGroup,
            params object[] FieldChoices)
        {

            if (web.AvailableFields.Contains(FieldId) == false)
            {

                string onColumnCreateXML = CoreHelper.GetFieldXml(FieldId, FieldName,
                    FieldDisplayName, SiteColumnGroup, DisplaceOnUpgrade, IsRequired, IsHidden,
                    FieldType, FieldFormat, FieldChoices);
            
                CoreHelper.CreateSiteColumn(web, FieldId, onColumnCreateXML);
                CoreHelper.UpdateColumnForDescription(web, FieldId, FoundationConstants.FieldDesc);
            }

        }

        /// <summary>
        /// Returns a dictionary of values from the list that is provided
        /// </summary>
        /// <param name="List">The name of the list to pull the values from</param>
        /// <param name="KeyColumnName">The name of the column that contains the key of the dictionary item</param>
        /// <param name="ValueColumnName">The name of the column that contains the value of the dictionary item</param>
        /// <returns></returns>
        public static Dictionary<string, string> ListItemDictionary(SPWeb web, string ListTitle, string KeyColumnName, string ValueColumnName)
        {
            
            try
            {
                SPList list = web.Lists.TryGetList(ListTitle);

                if (list == null)
                    throw new Exception("The List cannot be null if you want to convert it to a Dictionary");

                Dictionary<string, string> listItemDictionary = new Dictionary<string,string>();

                foreach (SPListItem listItem in list.Items)
                {
                    listItemDictionary.Add(listItem[KeyColumnName].ToString(), listItem[ValueColumnName].ToString());
                }

                return listItemDictionary;
                
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
                return null;
            }

            
            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="Name"></param>
        /// <param name="DisplayName"></param>
        /// <param name="Group"></param>
        /// <param name="DisplaceOnUpgrade"></param>
        /// <param name="IsRequired"></param>
        /// <param name="IsHideden"></param>
        /// <param name="fieldType"></param>
        /// <param name="format"></param>
        /// <param name="fieldChoices"></param>
        /// <returns></returns>
        public static string GetFieldXml(Guid id, string Name, string DisplayName, string Group, bool DisplaceOnUpgrade,
           bool IsRequired, bool IsHideden, FoundationEnums.FieldTypes fieldType, FoundationEnums.Format format, 
            params object[] fieldChoices)
        {
            StringBuilder sb = new StringBuilder();
            try
            {

                sb.Append("<Field");
                sb.Append(" ID='{" + id.ToString() + "}'");
                sb.Append(" Name='" + Name + "'");
                sb.Append(" StaticName='" + Name + "'");
                sb.Append(" DisplayName='" + DisplayName + "'");
                sb.Append(" Hidden='" + IsHideden + "'");
                sb.Append(" Required='" + IsRequired + "'");
                sb.Append(" DisplaceOnUpgrade='" + DisplaceOnUpgrade + "'");
                sb.Append(" Group='" + Group + "'");
                sb.Append(" Type='" + fieldType + "'");
                switch (fieldType)
                {

                    case FoundationEnums.FieldTypes.TaxonomyFieldType:
                        sb.Append(" ShowField='Term1033'");
                        sb.Append(" />");
                        break;
                    case FoundationEnums.FieldTypes.DateTime:
                        sb.Append(" format='" + format + "'");
                        sb.Append(" />");
                        break;
                    case FoundationEnums.FieldTypes.URL:
                        sb.Append(" format='" + format + "'");
                        sb.Append(" />");
                        break;
                    case FoundationEnums.FieldTypes.Calculated:
                        sb.Append(" ResultType=\"Text\"><Formula>=[Title]</Formula>");
                        sb.Append("<FieldRefs><FieldRef Name='Title'></FieldRef></FieldRefs>");
                        sb.Append("</Field>");
                        break;
                    case FoundationEnums.FieldTypes.Choice:
                        sb.Append(" Format='Dropdown' FillInChoice='FALSE'><CHOICES>");
                        
                        //added this to create display and value parameters
                        string[] fieldChoice = null;
                        try
                        {
                            fieldChoice = (string[])fieldChoices;
                        }
                        catch
                        {
                            fieldChoice = null;
                        }

                        if (fieldChoice != null)
                        {
                            sb.Append(ChoicesXml(fieldChoice));
                        }
                        else
                        {
                            if (fieldChoices[0] != null)
                            {
                                Dictionary<string, string> fieldDict = fieldChoices[0] as Dictionary<string, string>;
                                sb.Append(ChoicesXml(fieldDict));
                            }                           
                        }

                        sb.Append("</CHOICES>");
                        sb.Append("</Field>");
                        break;

                    case FoundationEnums.FieldTypes.Lookup:
                        sb.Append(" List='Lists/" + fieldChoices[0] + "'");
                        sb.Append(" ShowField='" + fieldChoices[1] + "' PrependId='TRUE'");
                        sb.Append(" />");
                        break;
                    default:
                        sb.Append(" />");
                        break;

                }

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return sb.ToString();

        }

        /// <summary>
        /// Creates the XML needed to create a SPFieldChoice from a dictionary
        /// </summary>
        /// <param name="choiceDictionary"></param>
        /// <returns></returns>
        private static string ChoicesXml(Dictionary<string, string> choiceDictionary)
        {
            StringBuilder choicesXml = new StringBuilder();


            foreach (KeyValuePair<string, string> choice in choiceDictionary)
            {
                choicesXml.Append("<CHOICE Value=\"");
                choicesXml.Append(choice.Value); 
                choicesXml.Append("\">");
                choicesXml.Append(choice.Key);
                choicesXml.Append("</CHOICE>");
            }

            return choicesXml.ToString();

        }

        /// <summary>
        /// Creates the XML needed to create a SPFieldChoice from a string array
        /// </summary>
        /// <param name="Choices"></param>
        /// <returns></returns>
        private static string ChoicesXml(string[] Choices)
        {
            StringBuilder choicesXml = null;


            foreach (string choice in Choices)
            {
                choicesXml.Append("<CHOICE Value=\"");
                choicesXml.Append(choice);
                choicesXml.Append("\">");
                choicesXml.Append(choice);
                choicesXml.Append("</CHOICE>");
            }


            return choicesXml.ToString();

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="Name"></param>
        /// <param name="DisplayName"></param>
        /// <param name="Group"></param>
        /// <param name="DisplaceOnUpgrade"></param>
        /// <param name="IsRequired"></param>
        /// <param name="IsHideden"></param>
        /// <param name="LookupField"></param>
        /// <returns></returns>
        public static string GetFieldXmlForSelfLookup(Guid id, string Name, string DisplayName, string Group, bool DisplaceOnUpgrade,
           bool IsRequired, bool IsHideden, string LookupField)
        {
            StringBuilder sb = new StringBuilder();
            try
            {

                sb.Append("<Field");
                sb.Append(" ID='{" + id.ToString() + "}'");
                sb.Append(" Name='" + Name + "'");
                sb.Append(" StaticName='" + Name + "'");
                sb.Append(" DisplayName='" + DisplayName + "'");
                sb.Append(" Hidden='" + IsHideden + "'");
                sb.Append(" Required='" + IsRequired + "'");
                sb.Append(" DisplaceOnUpgrade='" + DisplaceOnUpgrade + "'");
                sb.Append(" Group='" + Group + "'");
                sb.Append(" Type='Lookup'");
                sb.Append(" List='Self'");
                sb.Append(" ShowField='" + LookupField + "' PrependId='TRUE'");
                sb.Append(" />");


            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return sb.ToString();
        }
        /// <summary>
        /// Check for FieldLink
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="fieldId"></param>
        /// <returns></returns>
        public static bool HasFieldLink(SPContentType contentType, Guid fieldId)
        {
            bool found = false;
            try
            {
                foreach (SPFieldLink fl in contentType.FieldLinks)
                {
                    string name = fl.Name;
                    string displayname = fl.DisplayName;
                    if (fl.Id == fieldId)
                    {
                        found = true;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return found;
        }
        /// <summary>
        /// Checks for List Existance
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName"></param>
        /// <returns></returns>
        public static bool ListExists(SPWeb web, string listName)
        {
            bool found = false;
            try
            {
                found = web.Lists.Cast<SPList>().Any(list => string.Equals(list.Title, listName));
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return found;

        }
        /// <summary>
        /// Updtaes Site column Description
        /// </summary>
        /// <param name="web"></param>
        /// <param name="Column"></param>
        /// <param name="Description"></param>
        public static void UpdateColumnForDescription(SPWeb web, Guid Column, string Description)
        {
            try
            {
                Guid webSafe = CoreHelper.AllowUnSafeUpdates(ref web);
                web.Fields[Column].Description = Description;
                web.Fields[Column].Update();
                web.Update();
                CoreHelper.AllowUnSafeUpdates(ref web, webSafe);
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
        }
      
        ////    return DisplayName;
        ////}
        /// <summary>
        /// Check for Event Receiver exists
        /// </summary>
        /// <param name="web"></param>
        /// <param name="ListName"></param>
        /// <param name="EventReceiverID"></param>
        /// <returns></returns>
        public static bool EventReceiverExists(SPWeb web, string ListName, Guid EventReceiverID)
        {

            bool found = false;
            try
            {
                if (web.Lists[ListName].EventReceivers[EventReceiverID] != null)
                    found = true;
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return found;


        }
        /// <summary>
        /// Delting all ListItem from a given list
        /// </summary>
        /// <param name="web"></param>
        /// <param name="list"></param>
        public static void DelteAllListItem(SPWeb web, SPList list)
        {
            try
            {

                StringBuilder sbDelete = new StringBuilder();
                // Build Batch Xml, so that it will be fast in deleting
                sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
                string command = "<Method><SetList Scope=\"Request\">" + list.ID +
                         "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";
                foreach (SPListItem item in list.Items)
                {
                    sbDelete.Append(string.Format(command, item.ID.ToString()));
                }
                sbDelete.Append("</Batch>");
                string deleteCMD = sbDelete.ToString();
                Guid webSafe = CoreHelper.AllowUnSafeUpdates(ref web);
                web.ProcessBatchData(deleteCMD);
                CoreHelper.AllowUnSafeUpdates(ref web, webSafe);

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
        }

        /// <summary>
        /// IsRoleExists
        /// </summary>
        /// <param name="web"></param>
        /// <param name="RoleName"></param>
        /// <returns></returns>
        public static bool IsRoleExists(SPWeb web, string RoleName)
        {
            bool IsExists = false;
            foreach (SPRoleDefinition role in web.RoleDefinitions)
            {
                if (role.Name == RoleName)
                {
                    IsExists = true;
                }
            }
            return IsExists;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="web"></param>
        /// <param name="ListName"></param>
        /// <param name="ListTemplateType"></param>
        /// <param name="ListDescription"></param>
        /// <param name="ContentTypeName"></param>
        /// <param name="OnQuickLaunch"></param>
        /// <param name="RemoveDefaultContentType"></param>
        /// <param name="ViewFieldDisplayNames"></param>
        /// <returns></returns>
        public static SPList CreateList(SPWeb web, string ListName, SPListTemplateType ListTemplateType,
            string ListDescription, string ContentTypeName, bool OnQuickLaunch, bool RemoveDefaultContentType,
            params string[] ViewFieldDisplayNames)
        {
            Guid listGuid;

            try
            {
                if (web.Lists.TryGetList(ListName) == null)
                {
                    // set unsafe updates
                    Guid webSafe = AllowUnSafeUpdates(ref web);

                    if (string.IsNullOrEmpty(ListDescription))
                    {
                        ListDescription = FoundationConstants.ListDesc;
                    }

                    listGuid = web.Lists.Add(ListName, ListDescription, ListTemplateType);

                    // get List
                    SPList list = web.Lists[listGuid];

                    list.Title = ListName;
                    list.OnQuickLaunch = OnQuickLaunch;
                    list.ContentTypesEnabled = true;

                    // add our content type
                    list.ContentTypes.Add(web.Site.RootWeb.ContentTypes[ContentTypeName]);

                    //remove the default Item content type
                    if (RemoveDefaultContentType)
                    {
                        list.ContentTypes.Delete(list.ContentTypes[FoundationConstants.ItemContentTypeName].Id);
                    }
                    
                    //Make sure changes are committed to the list
                    list.Update();

                    if (ViewFieldDisplayNames != null)
                    {
                        //views
                        SPView defaultView = list.DefaultView;

                        defaultView.ViewFields.DeleteAll();

                        foreach (string fieldName in ViewFieldDisplayNames)
                        {
                            defaultView.ViewFields.Add(fieldName);
                        }

                        defaultView.Update();
                        list.Update();
                    }
                    
                    web.Update();

                    CoreHelper.AllowUnSafeUpdates(ref web, webSafe);

                    return list;

                }

                return null;
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
                return null;

            }
        }

        /// <summary>
        /// Creates a blank default list of the type specified
        /// </summary>
        /// <param name="web"></param>
        /// <param name="ListName"></param>
        /// <param name="ListTemplateType"></param>
        /// <param name="ListDescription"></param>
        /// <returns></returns>
        public static SPList CreateList(SPWeb web, string ListName, SPListTemplateType ListTemplateType,
            string ListDescription)
        {
            Guid listGuid;
            
            try
            {
                // set unsafe updates
                Guid webSafe = CoreHelper.AllowUnSafeUpdates(ref web);

                listGuid = web.Lists.Add(ListName, ListDescription, ListTemplateType);

                // get List
                SPList list = web.Lists[listGuid];

                list.OnQuickLaunch = false;
                list.ContentTypesEnabled = false;
                
                list.Update();

                web.Update();

                CoreHelper.AllowUnSafeUpdates(ref web, webSafe);

                return list;

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
                return null;
            }
           
        }

        /// <summary>
        /// WARNING! This will delete all of your list items and remove the list 
        /// from the specified web. Use with caution and only if you know what you are doing!
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listTitle"></param>
        /// <returns></returns>
        public static bool RemoveList(SPWeb web, string listTitle)
        {
            try
            {
                if (web.Lists.TryGetList(listTitle) != null)
                {
                    SPList list = web.Lists[listTitle];
                    
                    DelteAllListItem(web, list);

                    Guid webSafe = CoreHelper.AllowUnSafeUpdates(ref web);

                    list.Delete();
                    web.Update();        
                                
                    CoreHelper.AllowUnSafeUpdates(ref web, webSafe);

                    return true;

                }

                return false;

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
                return false;
            }
                       
        }

        /// <summary>
        /// Creates a content type in the specified web
        /// </summary>
        /// <param name="web"></param>
        /// <param name="ContentTypeId"></param>
        /// <param name="ContentTypeName"></param>
        /// <param name="ContentTypeGroup"></param>
        /// <param name="ContentTypeDescription"></param>
        public static SPContentType CreateContentType(SPWeb web, string ContentTypeId, string ContentTypeName, 
            string ContentTypeGroup, string ContentTypeDescription)
        {
            SPContentTypeId contentTypeId = new SPContentTypeId(ContentTypeId);
            SPContentType contentType = web.ContentTypes[contentTypeId];

            try
            {
                if (contentType == null)
                {
                    if (string.IsNullOrEmpty(ContentTypeDescription))
                    {
                        ContentTypeDescription = FoundationConstants.FieldDesc;
                    }

                    contentType = new SPContentType(contentTypeId, web.ContentTypes, ContentTypeName);
                    contentType.Group = ContentTypeGroup;
                    contentType.Description = ContentTypeDescription;
                    
                    web.ContentTypes.Add(contentType);
                    web.Update();

                    return web.ContentTypes[contentTypeId];
                }

                return contentType;
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
                return null;
            }

        }


        /// <summary>
        /// Removes the specified SPContentType from the specified web
        /// </summary>
        /// <param name="web"></param>
        /// <param name="contentTypeName"></param>
        /// <returns></returns>
        public static bool RemoveContentType(SPWeb web, string contentTypeName)
        {
            try
            {
                SPContentType contentType = web.ContentTypes[contentTypeName];

                if (contentType != null)
                {

                    web.ContentTypes[contentTypeName].Delete();
                    web.Update();

                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
                return false;
            }                    

        }

        #endregion

        #region Managed Mata Data Column related functions
        /// <summary>
        ///  This will provision the Managed Metadata Service with the Taxonomy needed
        /// </summary>
        /// <param name="web"></param>
        /// <param name="FieldId"></param>
        /// <param name="TermStoreName"></param>
        /// <param name="TermStoreGroup"></param>
        /// <param name="TermSetName"></param>
        /// <param name="TermName"></param>
        public static void ProvisionMetadataSiteColumn(SPWeb web, Guid FieldId, string TermStoreName, string TermStoreGroup, string TermSetName, string TermName)
        {
            try
            {
                if (web.Fields.Contains(FieldId))
                {
                    TaxonomySession session = new TaxonomySession(web.Site);
                    // If Managed MataData Services attached to Web application, connect to it.
                    if (session.TermStores.Count != 0)
                    {

                        var termStore = GetTermStore(session, TermStoreName);
                        var group = GetTermGroup(termStore, TermStoreGroup);
                        var termSet = GetTermSet(group, TermSetName);
                        var term = GetTerm(termSet, TermName);

                        TaxonomyField field = web.Fields[FieldId] as TaxonomyField;
                        if (field != null)
                        {
                            // // Logging.TraceToDeveloper("Connecting to Managed Matadata Service", AreaCategorySettings.Category.FeatureReceiver);
                            if (web.Fields.Contains(FieldId))
                            {
                                // Connect to Managed Matadata Service
                                field.SspId = termSet.TermStore.Id;
                                field.TermSetId = termSet.Id;
                                field.TargetTemplate = string.Empty;
                                field.AnchorId = Guid.Empty;
                                // Default value may need to set it, but not now... need to check requiremnets.
                                //field.DefaultValue = SetDefaultValue(termSet,term); 
                                field.Update();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
        }

        /// <summary>
        /// Not tested method. But this the way to set defaul values for MMS columns
        /// </summary>
        /// <param name="termset"></param>
        /// <param name="term"></param>
        /// <returns></returns>
        private static string SetDefaultValue(TermSet termset, Term term)
        {
            string ReturnValue = string.Empty;
            try
            {

                int cnt = GetTermNumber(termset, term);
                //field.DefaultValue	"1;#Default|3ad6ff9d-1b55-4634-8474-f758fca29a7f"
                ReturnValue = cnt.ToString() + ";#" + term.Name + "|" + term.Id.ToString();

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return ReturnValue;

        }
        /// <summary>
        /// Not tested method. But this the way to set defaul values for MMS columns
        /// </summary>
        /// <param name="termset"></param>
        /// <param name="term"></param>
        /// <returns></returns>
        private static int GetTermNumber(TermSet termset, Term term)
        {
            int returnvalue = 0;
            try
            {

                for (int i = 0; i < termset.Terms.Count; i++)
                {
                    if (termset.Terms[i].Name == term.Name)
                    {
                        returnvalue = i + 1;
                    }
                }

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return returnvalue;
        }
        /// <summary>
        /// Getting TermStore
        /// </summary>
        /// <param name="session"></param>
        /// <param name="TermStoreName"></param>
        /// <returns></returns>
        private static TermStore GetTermStore(TaxonomySession session, string TermStoreName)
        {
            TermStore termStore = null;
            try
            {

                if (session.TermStores.Count == 1)
                    termStore = session.TermStores[0];
                else
                    termStore = session.TermStores[TermStoreName];

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return termStore;
        }
        /// <summary>
        /// Getting TermGroup
        /// </summary>
        /// <param name="termStore"></param>
        /// <param name="TermStoreGroup"></param>
        /// <returns></returns>
        private static Group GetTermGroup(TermStore termStore, string TermStoreGroup)
        {
            Group group = null;
            try
            {

                group = termStore.Groups[TermStoreGroup];

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return group;
        }
        /// <summary>
        /// Getting TermSet
        /// </summary>
        /// <param name="group"></param>
        /// <param name="TermSetName"></param>
        /// <returns></returns>
        private static TermSet GetTermSet(Group group, string TermSetName)
        {
            TermSet termSet = null;
            try
            {

                termSet = group.TermSets[TermSetName];

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return termSet;
        }
        /// <summary>
        /// Getting Term
        /// </summary>
        /// <param name="termSet"></param>
        /// <param name="TermName"></param>
        /// <returns></returns>
        private static Term GetTerm(TermSet termSet, string TermName)
        {
            Term term = null;
            try
            {

                term = termSet.Terms[TermName];

            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
            return term;
        }

        /// <summary>
        /// This will provision the Managed Metadata Service with the Taxonomy needed
        /// </summary>        
        public static void ProvisionTaxonomy(SPSite oSite, string TermStoreName, string TermStoreGroup, string TermSetName, string TermName)
        {
            TaxonomySession oTaxSession;
            TermStore oTermStore;
            Group oTermGroup;
            TermSet oTermSet;
            Term oTerm;

            try
            {

                oTaxSession = new TaxonomySession(oSite);
                oTermStore = oTaxSession.DefaultSiteCollectionTermStore;

                try
                {
                    oTermGroup = oTermStore.Groups[TermStoreGroup];
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    Logging.LogToULS(string.Format("Term Store Group Does Not Exist: {0}", ex.Message), FoundationConstants.standardsLog);
                    oTermGroup = oTermStore.CreateGroup(TermStoreGroup);
                    oTermGroup.Description = TermStoreGroup + " Term Store Group";
                    oTermStore.CommitAll();
                }

                try
                {
                    oTermSet = oTermGroup.TermSets[TermSetName];
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    Logging.LogToULS(string.Format("Term Set Does Not Exist: {0}", ex.Message), FoundationConstants.standardsLog);
                    oTermSet = oTermGroup.CreateTermSet(TermSetName);
                    oTermSet.Description = TermSetName + " Term Set";
                    oTermStore.CommitAll();
                }

                try
                {
                    oTerm = oTermSet.Terms[TermName];
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    Logging.LogToULS(string.Format("Term Does Not Exist: {0}", ex.Message), FoundationConstants.standardsLog);
                    oTerm = oTermSet.CreateTerm(TermName, oTermStore.DefaultLanguage);
                    oTermStore.CommitAll();
                }
            }
            catch (Exception ex)
            {
                Logging.LogError(ex, FoundationConstants.standardsLog);
            }
        }

        #endregion

        #region Misc

        /// <summary>
        /// WebRelativeRedirect
        /// </summary>
        /// <param name="relativePath"></param>
        /// <param name="web"></param>
        /// <returns></returns>
        public static string WebRelativeURL(string relativePath, SPWeb web)
        {
            if (string.IsNullOrEmpty(relativePath))
            {
                return web.Url;
            }

            relativePath = relativePath.Substring(0, 1) == "/" ? relativePath : "/" + relativePath;
            return web.Url + relativePath;
        }
        /// <summary>
        /// WebRelativeRedirectQueryString
        /// </summary>
        /// <param name="relativePath"></param>
        /// <param name="web"></param>
        /// <param name="queryString"></param>
        /// <param name="queryStringValue"></param>
        /// <returns></returns>
        public static string WebRelativeURLQueryString(string relativePath, SPWeb web, string queryString, string queryStringValue)
        {
            if (string.IsNullOrEmpty(relativePath))
            {
                return web.Url + "?" + queryString + "=" + queryStringValue;
            }

            relativePath = relativePath.Substring(0, 1) == "/" ? relativePath : "/" + relativePath;
            return web.Url + relativePath + "?" + queryString + "=" + queryStringValue;
        }





        private const string SharePointServerPublishingInfrastructureGuid = "f6924d36-2fa8-4f0b-b16d-06b7250180fa";
        private const string SharePointServerPublishingGuid = "94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb";
        private void ActivatePublishingInfrastucture(SPSite site)
        {
            // create Guid for the Feature
            Guid Id = new Guid("{" + SharePointServerPublishingInfrastructureGuid + "}");

            if (site.Features[Id] == null)
                // Activate the Feature
                site.Features.Add(Id);
        }
        private void DeactivatePublishingInfrastucture(SPSite site)
        {
            // create Guid for the Feature
            Guid Id = new Guid("{" + SharePointServerPublishingInfrastructureGuid + "}");

            if (site.Features[Id] != null)
                // Deactivate the Feature
                site.Features.Remove(Id);
        }
        #endregion

        #region Versioning
        public static class Versioning
        {
            /// <summary>
            /// Get's the AssemblyFileVersion of the passed assembly
            /// </summary>
            /// <param name="thisAssembly">Assembly.GetExecutingAssembly()</param>
            /// <returns></returns>
            public static string GetSolutionVersion()
            {
                Assembly thisAssembly = Assembly.GetCallingAssembly();
                FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(thisAssembly.Location);
                return fvi.FileVersion;
            }
            /// <summary>
            /// Get's the Feature version by the FQN of the Feature
            /// </summary>
            /// <param name="FeatureName"></param>
            /// <returns></returns>
            public static string GetFeatureVersion(string FeatureName)
            {
                SPFeatureDefinition d = SPFarm.Local.FeatureDefinitions[FeatureName];
                System.Version version = d.Version;
                return version.ToString();
            }
            /// <summary>
            /// Get's the AssemblyVersion of the passed assembly
            /// </summary>
            /// <param name="thisAssembly">Assembly.GetExecutingAssembly()</param>
            /// <returns></returns>
            public static string GetAssemblyVersion()
            {
                Assembly thisAssembly = Assembly.GetCallingAssembly();
                System.Version version = thisAssembly.GetName().Version;
                return version.ToString();
            }
        }
        #endregion

       

    }

    public class CAMLQueries
    {
        public static string GetQueryById(string ID)
        {
            return "<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">" + ID + "</Value></Eq></Where>";
        }

       

        public static string GetAppConfigItems(string acModule, string acGroup, string acKey)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<Where><And><Eq><FieldRef Name=\"AppConfigModule\" /><Value Type=\"Text\">");
            sb.Append(acModule);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigGroup\" /><Value Type=\"Text\">");
            sb.Append(acGroup);
            sb.Append("</Value></Eq>");
            
            sb.Append("<Eq><FieldRef Name=\"AppConfigKey\" /><Value Type=\"Text\">");
            sb.Append(acKey);
            sb.Append("</Value></Eq>");
            
            sb.Append("</And></And></Where>");

            return sb.ToString();
        }              

        public static string GetAppConfigItems(string acModule, string acGroup, string acKey, string acValue)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<Where><And><Eq><FieldRef Name=\"AppConfigModule\" /><Value Type=\"Text\">");
            sb.Append(acModule);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigGroup\" /><Value Type=\"Text\">");
            sb.Append(acGroup);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigKey\" /><Value Type=\"Text\">");
            sb.Append(acKey);
            sb.Append("</Value></Eq>");

            sb.Append("<Eq><FieldRef Name=\"AppConfigValue\" /><Value Type=\"Text\">");
            sb.Append(acValue);
            sb.Append("</Value></Eq>");

            sb.Append("</And></And></And></Where>");

            return sb.ToString();
        }

        public static string GetVersionedAppConfigItems(string acModule, string acGroup, string acKey, string acVersion)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<Where><And><Eq><FieldRef Name=\"AppConfigModule\" /><Value Type=\"Text\">");
            sb.Append(acModule);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigGroup\" /><Value Type=\"Text\">");
            sb.Append(acGroup);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigKey\" /><Value Type=\"Text\">");
            sb.Append(acKey);
            sb.Append("</Value></Eq>");

            sb.Append("<Eq><FieldRef Name=\"AppConfigVersion\" /><Value Type=\"Text\">");
            sb.Append(acVersion);
            sb.Append("</Value></Eq>");

            sb.Append("</And></And></And></Where>");

            return sb.ToString();
        }
     
        public static string GetVersionedAppConfigItems(string acModule, string acGroup, string acKey, string acValue, string acVersion)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<Where><And><Eq><FieldRef Name=\"AppConfigModule\" /><Value Type=\"Text\">");
            sb.Append(acModule);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigGroup\" /><Value Type=\"Text\">");
            sb.Append(acGroup);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigKey\" /><Value Type=\"Text\">");
            sb.Append(acKey);
            sb.Append("</Value></Eq>");

            sb.Append("<And><Eq><FieldRef Name=\"AppConfigValue\" /><Value Type=\"Text\">");
            sb.Append(acValue);
            sb.Append("</Value></Eq>");

            sb.Append("<Eq><FieldRef Name=\"AppConfigVersion\" /><Value Type=\"Text\">");
            sb.Append(acVersion);
            sb.Append("</Value></Eq>");

            sb.Append("</And></And></And></And></Where>");

            return sb.ToString();
        }
    }



}
